﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SuperMap.Data;
using SuperMap.Mapping;
using SuperMap.UI;
using SuperMap.Realspace;
using System.Diagnostics;
using System.Collections;
using System.Threading;
using SuperMap.Analyst.SpatialAnalyst;
using SuperMap.Data.Topology;


namespace WindowsFormsApplication8
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Start();
            button3.Enabled = false;
        }
        private void Start()
        {mapControl=new MapControl();
        workSpace = new Workspace();
        workSpacetree = new WorkspaceTree();
        layersControl = new LayersControl();
        mapControl.Location = new Point(300, 150);
        mapControl.Size = new Size(1600, 700);
        mapControl.Action = SuperMap.UI.Action.Select2;
        mapControl.SelectionTolerance = 0.66;
           
        workSpacetree.Location = new Point(0, 150);
        workSpacetree.Size = new Size(280, 345);
        workSpacetree.BorderStyle = BorderStyle.Fixed3D;
        workSpacetree.Visible = true;
        layersControl.Location = new Point(0,505);
        layersControl.Size = new Size(280, 345);
        this.Controls.Add(workSpacetree);
        this.Controls.Add(mapControl);
        this.Controls.Add(layersControl);
            workSpacetree.NodeMouseDoubleClick+=new TreeNodeMouseClickEventHandler(workSpacetree_NodeMouseDoubleClick);

            
        
        }
        private SuperMap.UI.MapControl mapControl;
        private SuperMap.UI.WorkspaceTree workSpacetree;
        private SuperMap.UI.LayersControl layersControl;
        public Workspace workSpace;
        public Datasource dataSource;
        public Dataset dataSet;
        public Relationship relationship;
        public Dataset StartPoints;

        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "smwu|*.smwu";
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.Cancel)
                return;
            else if (result == DialogResult.OK)
            {
                mapControl.Map.Layers.Clear();
                WorkspaceConnectionInfo workSpaceconnectioninfo;

                workSpace.Close();
                mapControl.Refresh();
                workSpaceconnectioninfo = new WorkspaceConnectionInfo(openFileDialog1.FileName);

                workSpace.Open(workSpaceconnectioninfo);
                workSpaceconnectioninfo.Dispose();
                mapControl.Map.Workspace = workSpace;
                workSpacetree.Workspace = workSpace;
                workSpacetree.Refresh();
                layersControl.Map = mapControl.Map;
            }

        }
        private void workSpacetree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            WorkspaceTreeNodeBase Node = e.Node as WorkspaceTreeNodeBase;
            Dataset Dataset = Node.GetData() as Dataset;




            dataSource = Dataset.Datasource;
            dataSet = Dataset;




            mapControl.Map.Layers.Add(Dataset, true);

            mapControl.Map.Refresh();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            form2.StartPosition = FormStartPosition.CenterScreen;

            form2.ShowDialog();
            if (form2.result != DialogResult.OK)
            {
                form2.Dispose(); return;

            }
            for (int i = 0; i < dataSource.Datasets.Count; i++)
            {
                if (form2.textBox1.Text == dataSource.Datasets[i].Name)
                {
                    MessageBox.Show("存在同名数据集请重新命名"); return;
                }
            }

            double Length = Convert.ToDouble(form2.textBox2.Text);
            DatasetVectorInfo datasetvectorinfo = new DatasetVectorInfo();
            datasetvectorinfo.IsFileCache = true;
            datasetvectorinfo.Type = DatasetType.Line;
            datasetvectorinfo.Name = form2.textBox1.Text;
            String RecordName = form2.textBox1.Text;
            form2.Dispose();
            if (dataSet.Type != DatasetType.Line)
            { MessageBox.Show("非线对象不能切割"); return; }
            DatasetVector datasetVector;
            datasetVector = dataSource.Datasets.Create(datasetvectorinfo);

            Recordset Record = datasetVector.GetRecordset(true, CursorType.Dynamic);

            DatasetVector daTasetVector = dataSet as DatasetVector;
            DatasetVector datAsetVector = dataSet as DatasetVector;
            Recordset reCordset = daTasetVector.GetRecordset(false, CursorType.Dynamic);

          //  Recordset recordset = datAsetVector.GetRecordset(false, CursorType.Dynamic);
            Recordset.BatchEditor editor = Record.Batch;
            editor.MaxRecordCount = 200000;


            editor.Begin();


            GeoLine[] line;
            GeoLine gEoline;

         //   recordset.MoveFirst();
            reCordset.MoveFirst();
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            while (!reCordset.IsEOF)
            {
                GeoLine geoline = reCordset.GetGeometry() as GeoLine;
                Record.AddNew(geoline);
                reCordset.MoveNext();
 
            }//复制一份数据集
            editor.Update();
            TopologyProcessingOptions TopologyProcessingOptions = new TopologyProcessingOptions();
            TopologyProcessingOptions.AreAdjacentEndpointsMerged = false;
            TopologyProcessingOptions.AreDuplicatedLinesCleaned = false;
            TopologyProcessingOptions.AreLinesIntersected = true;
            TopologyProcessingOptions.AreOvershootsCleaned = false;
            TopologyProcessingOptions.ArePseudoNodesCleaned = false;
            TopologyProcessingOptions.AreRedundantVerticesCleaned = false;
            TopologyProcessingOptions.AreUndershootsExtended = false;
            TopologyProcessing.Clean(Record.Dataset, TopologyProcessingOptions);
            datasetVector = dataSource.Datasets[RecordName] as DatasetVector;
            Record = datasetVector.GetRecordset(false,CursorType.Dynamic);
            
            editor = Record.Batch;
            editor.MaxRecordCount = 200000;

            Record.MoveFirst();
            editor.Begin();
            List<GeoLine> Line = new List<GeoLine>();
            while (!Record.IsEOF)
            {
                GeoLine geoline = Record.GetGeometry() as GeoLine;
                List<GeoLine> geoLine = new List<GeoLine>();
                geoLine = distanceclip(geoline, Length);
                for (int i = 0; i < geoLine.Count; i++)
                {

                    Line.Add(geoLine[i]);


                }
                Record.MoveNext();

            }
            Record.DeleteAll();

            for(int i=0;i<Line.Count;i++)
                Record.AddNew(Line[i]);

            

                editor.Update();
            /*while (!reCordset.IsEOF)
            {
                GeoLine geoline = reCordset.GetGeometry() as GeoLine; 
                List<GeoLine> Line = new List<GeoLine>();
                QueryParameter queryParameter = new QueryParameter();
                queryParameter.CursorType = CursorType.Static;
                queryParameter.HasGeometry = true;
                queryParameter.SpatialQueryMode = SpatialQueryMode.Intersect;
                queryParameter.SpatialQueryObject = geoline;
                Recordset recordSet = daTasetVector.Query(queryParameter);

                if (recordSet.RecordCount == 1)
                {
                    ;
                }
                else
                {
                    recordSet.MoveFirst();
                    while (!recordSet.IsEOF)
                    {
                        if (Line.Count == 0)
                        {

                            gEoline = recordSet.GetGeometry() as GeoLine;
                            if (Geometrist.HasTouch(gEoline, geoline))
                            {
                                Geometry geopoint = Geometrist.Intersect(gEoline, geoline);
                                if (geopoint == null) { ;}
                                else
                                {
                                    line = Geometrist.SplitLine(geoline, geopoint, 0.0000001);


                                    for (int i = 0; i < line.Length; i++)
                                    { if (line[i].Length > 0.1) Line.Add(line[i]); }
                                }
                            }
                            recordSet.MoveNext();

                        }
                        else
                        {
                            int count = Line.Count;
                            gEoline = recordSet.GetGeometry() as GeoLine;

                            for (int k = 0; k < count; k++)
                            {
                                GeoLine geOline = Line[k];
                                if (Geometrist.HasTouch(geOline, geoline))
                                {
                                    Geometry geopoint = Geometrist.Intersect(gEoline, geoline);
                                    if (geopoint == null) { ;}
                                    else
                                    {
                                        line = Geometrist.SplitLine(geOline, geopoint, 0.00000001);
                                        if (line.Length > 0)
                                        {
                                            Line.RemoveAt(k);
                                            for (int j = 0; j < line.Length; j++)
                                            { if (line[j].Length > 0.01) Line.Add(line[j]); }
                                        }
                                    }
                                }
                            }
                            recordSet.MoveNext();
                        }

                    }

                }

               
                    if (Line.Count == 0)
                    {
                        Record.AddNew(geoline);
                        List<GeoLine> geoLine = new List<GeoLine>();
                        geoLine = distanceclip(geoline, Length);
                        for (int i = 0; i < geoLine.Count; i++)
                        {
                           
                                Record.AddNew(geoLine[i]);
                               
                            
                        }
                    }
                    else
                    {
                        List<GeoLine> Line1 = new List<GeoLine>();
                        for (int i = 0; i < Line.Count; i++)
                        {
                            Line1.Add(Line[i]);

                        }


                        List<GeoLine> geoLine = new List<GeoLine>();
                        int Count = Line.Count;
                        Line.Clear();
                        for (int i = 0; i < Count; i++)
                        {
                            
                            geoLine = distanceclip(Line1[i], Length);
                           for (int j = 0; j < geoLine.Count; j++)
                            { Line.Add(geoLine[j]); }


                        }
                        
                        for (int i = 0; i < Line.Count; i++)
                        {
                            if (Line[i].Length != 0)
                            {
                                Record.AddNew(Line[i]);
                               
                            }
                        }
                    }  
                
                reCordset.MoveNext();



                


            }*/
                datasetVector = dataSource.Datasets[RecordName] as DatasetVector;
                datasetVector.IsReadOnly = false;
                FieldInfo fieldInfo = new FieldInfo();
                fieldInfo.Name = "Power";
                fieldInfo.Caption = "Power";
                fieldInfo.DefaultValue = "0";
                fieldInfo.Type = FieldType.Int32;
                fieldInfo.IsRequired = true;
                FieldInfos fieldInfos = datasetVector.FieldInfos;
                fieldInfos.Add(fieldInfo);
            



            workSpacetree.Refresh();

                mapControl.Map.Refresh();
                
                stopwatch.Stop();
                MessageBox.Show("Finish,it takes"+stopwatch.Elapsed.ToString());

        }


        public List<GeoLine> distanceclip(Geometry geometry, double a)
        {
            List<GeoPoint> geoPoints = new List<GeoPoint>();
            List<GeoLine> geoLines = new List<GeoLine>();
            GeoLine[] geOline;
            GeoLine geoline = geometry as GeoLine;
            Point2D point = new Point2D();

            double length = a;


            for (int i = 1; i * length < geoline.Length; i++)
            {
                point = geoline.FindPointOnLineByDistance(i * length);
                geoPoints.Add(new GeoPoint(point));
            }
            
            geoLines.Add(geoline);
            if (geoPoints.Count == 0)
            {
                return geoLines; 
            }
            
            else
            {
                for (int j = 0; j < geoPoints.Count - 1; j++)
                {

                    GeoLine[] geoliNe = Geometrist.SplitLine(geoLines[geoLines.Count - 1], geoPoints[j], 0.0000001);

                    geoLines.RemoveAt(geoLines.Count - 1);
                    geoLines.Add(geoliNe[0]); geoLines.Add(geoliNe[1]);
                }
                if (geoLines[geoLines.Count - 1].Length - length > length/2)
                {
                    GeoLine[] geoliNE = Geometrist.SplitLine(geoLines[geoLines.Count - 1], geoPoints[geoPoints.Count - 1], 0.0000001);
                    geoLines.RemoveAt(geoLines.Count - 1);
                    

                   geoLines.Add(geoliNE[0]); geoLines.Add(geoliNE[1]); 
                    
                }
                else return geoLines;
                 

                
                

            }//保证geoLines中的最后一位必定是要切割的线
            
            return geoLines;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            relationship = new Relationship();
            DatasetVector daTasetVector = dataSet as DatasetVector;
            DatasetVector datAsetVector = dataSet as DatasetVector;
            relationship.Create(daTasetVector);
            stopwatch.Stop();
            MessageBox.Show(stopwatch.Elapsed.ToString());
            
            
            DatasetVector datasetVector = dataSet as DatasetVector;
            Recordset Recordset = datasetVector.GetRecordset(false, CursorType.Dynamic);
            Recordset.MoveFirst();
            Recordset.BatchEditor editor = Recordset.Batch;
            editor.MaxRecordCount = 200000;


            editor.Begin();
            while (!Recordset.IsEOF)
            {
                if ((int)Recordset.GetFieldValue("SmUserID") != 0)
                {
                    
                    Recordset.SetFieldValue("SmUserID", 0);
                    
                    
                }
                
               
            Recordset.MoveNext();
            }
            editor.Update();
            Recordset.MoveFirst();
            editor = Recordset.Batch;
            editor.MaxRecordCount = 200000;
            editor.Begin();
            while (!Recordset.IsEOF)
            {
                if ((int)Recordset.GetFieldValue("SmUserID") != 0)
                {

                    Recordset.SetFieldValue("SmUserID", 0);


                }


                Recordset.MoveNext();
            }
            editor.Update();

              button3.Enabled = true;

        }

        private void button3_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            Queue<int> queue = new Queue<int>();
            //设置起源点
            
            DatasetVector startPoints = StartPoints as DatasetVector;
            Recordset recordset = startPoints.GetRecordset(false,CursorType.Static);
            recordset.MoveFirst();
            
            DatasetVector datasetVector = dataSet as DatasetVector;
            while(!recordset.IsEOF)
            {   Geometry Geometry = recordset.GetGeometry();
                QueryParameter queryparameter = new QueryParameter();
                queryparameter.HasGeometry = true;
                queryparameter.SpatialQueryMode = SpatialQueryMode.Intersect;
                queryparameter.SpatialQueryObject = Geometry;
                Recordset rEcordset= datasetVector.Query(queryparameter);
                if (!rEcordset.IsEmpty)
                { queue.Enqueue(rEcordset.GetID());
                relationship.unit[relationship.dictionary[rEcordset.GetID()]].visit = true; rEcordset.MoveFirst();
                rEcordset.Edit(); rEcordset.SetFieldValue("Power", recordset.GetFieldValue("Power")); rEcordset.Update(); rEcordset.Edit();
                rEcordset.SetFieldValue("SmUserID", recordset.GetID()); rEcordset.Update();
                }
                else
                {
                    BufferAnalystParameter bufferanalystparameter = new BufferAnalystParameter();
                    bufferanalystparameter.RadiusUnit = BufferRadiusUnit.Meter;
                    bufferanalystparameter.LeftDistance = 100;
                    bufferanalystparameter.RightDistance = 100;
                    GeoRegion georegion = BufferAnalystGeometry.CreateBuffer(Geometry, bufferanalystparameter);
                    queryparameter = new QueryParameter();
                    queryparameter.HasGeometry = true;
                    queryparameter.SpatialQueryMode = SpatialQueryMode.Intersect;
                    queryparameter.SpatialQueryObject = georegion;
                    rEcordset = datasetVector.Query(queryparameter);
                    rEcordset.MoveFirst();
                    int min = rEcordset.GetID();
                    double distance = Geometrist.Distance(rEcordset.GetGeometry(), Geometry);
                    rEcordset.MoveNext();
                    while (!rEcordset.IsEOF)
                    {
                        if (distance > Geometrist.Distance(rEcordset.GetGeometry(), Geometry))
                        { min = rEcordset.GetID(); distance = Geometrist.Distance(rEcordset.GetGeometry(), Geometry);}
                        rEcordset.MoveNext();
                    }
                    relationship.unit[relationship.dictionary[min]].visit = true;
                    rEcordset.SeekID(min);
                    rEcordset.Edit(); rEcordset.SetFieldValue("Power", recordset.GetFieldValue("Power")); rEcordset.Update(); rEcordset.Edit();
                    rEcordset.SetFieldValue("SmUserID", recordset.GetID()); rEcordset.Update();
                    queue.Enqueue(min);
                }
                recordset.MoveNext();

            }
            
            
            Recordset Recordset = datasetVector.GetRecordset(false, CursorType.Dynamic);
            
            //广度搜索

            Recordset.BatchEditor editor = Recordset.Batch;
            editor.MaxRecordCount = 200000;


            editor.Begin();
            while (queue.Count != 0)
            {
                Recordset.SeekID(queue.Peek());
                int power = (int)Recordset.GetFieldValue("Power");
                int UserID =(int) Recordset.GetFieldValue("SmUserID");
                Queue<int> quEue = new Queue<int>();
                quEue.Enqueue(queue.Peek());
                int ShouldDequeue = 1;
                    for (int j = 0; j < power&&quEue.Count>0; j++)
                    {
                        
                        int times = ShouldDequeue;
                       // for (int l = 0; l < ShouldDequeue; l++)  
                        ShouldDequeue = 0;
                        for (int k = 0; k < times; k++)
                        { List<int> list = relationship.Search(quEue.Peek()); quEue.Dequeue();
                            for (int i = 0; i < list.Count; i++)
                            {
                                if (relationship.unit[relationship.dictionary[list[i]]].visit == false)
                                {
                                    quEue.Enqueue(list[i]);

                                    Recordset.SeekID(list[i]);
                                   // Recordset.Edit(); 
                                    Recordset.SetFieldValue("Power", power);
                                   // Recordset.Update(); 
                                   // Recordset.Edit();
                                    Recordset.SetFieldValue("SmUserID", UserID);
                                    //Recordset.Update();
                                    ShouldDequeue++;
                                    
                                    relationship.unit[relationship.dictionary[list[i]]].visit = true;
                                }
                            }
                        }
                    }
                    while (quEue.Count > 0)
                        queue.Enqueue(quEue.Dequeue());
                    queue.Dequeue();
            }
            editor.Update();
            
            
            
            
                 ThemeUnique theme = new ThemeUnique();
                theme = ThemeUnique.MakeDefault(datasetVector, "SmUserID");
                GeoStyle geostyle = new GeoStyle();
                int num = theme.Count;
                switch (num)
                {
                    case 3:
                        geostyle.LineColor = Color.Black;
                        geostyle.LineWidth = 0.3;
                        theme[2].Style = geostyle;

                        geostyle.LineColor = Color.BlueViolet;
                        geostyle.LineWidth = 0.5;
                        theme[1].Style = geostyle;
                        geostyle.LineColor = Color.Red;
                        geostyle.LineWidth = 1.0;
                        theme[0].Style = geostyle;
                        break;
                    case 2:
                        geostyle.LineColor = Color.BlueViolet;
                        geostyle.LineWidth = 0.5;
                        theme[1].Style = geostyle;
                        geostyle.LineColor = Color.Red;
                        geostyle.LineWidth = 1.0;
                        theme[0].Style = geostyle;
                        break;
                    default:
                        break;


                } mapControl.Map.Refresh(); Layer layerTheme = mapControl.Map.Layers.Add(datasetVector, theme, true);

                stopwatch.Stop();
                MessageBox.Show("finished in"+stopwatch.Elapsed.ToString());
            
            
            //建立专题图
            
           
            
          
            
        }
        public void Mapfresh()
        {
            DatasetVector datasetVector = dataSet as DatasetVector;


            mapControl.Map.Layers.Clear(); ThemeUnique theme = new ThemeUnique();
            theme = ThemeUnique.MakeDefault(datasetVector, "SmUserID");
            GeoStyle geostyle = new GeoStyle();
            int num = theme.Count;
            switch (num)
            {
                case 3:
                    geostyle.LineColor = Color.Black;
                    geostyle.LineWidth = 0.3;
                    theme[0].Style = geostyle;

                    geostyle.LineColor = Color.BlueViolet;
                    geostyle.LineWidth = 0.5;
                    theme[2].Style = geostyle;
                    geostyle.LineColor = Color.Red;
                    geostyle.LineWidth = 1.0;
                    theme[1].Style = geostyle;
                    break;
                case 2:
                    geostyle.LineColor = Color.BlueViolet;
                    geostyle.LineWidth = 0.5;
                    theme[1].Style = geostyle;
                    geostyle.LineColor = Color.Red;
                    geostyle.LineWidth = 1.0;
                    theme[0].Style = geostyle;
                    break;
                default:
                    break;


            } mapControl.Map.Refresh(); Layer layerTheme = mapControl.Map.Layers.Add(datasetVector, theme, true);
        }
        public void WideSearch()
        {
            Queue<int> queue = new Queue<int>();
            //设置起源点
            Selection[] select;
            DatasetVector datasetVector = dataSet as DatasetVector;
            select = mapControl.Map.FindSelection(true);
            Selection selection = select[0];
            Recordset recordset = selection.ToRecordset();
            Recordset Recordset = datasetVector.GetRecordset(false, CursorType.Dynamic);
            queue.Enqueue(recordset.GetID());
            Recordset.SeekID(recordset.GetID());
            Recordset.Edit();
            //广度搜索
            Recordset.SetFieldValue("SmUserID", 1);
            relationship.unit[relationship.dictionary[queue.Peek()]].visit = true;
            while (queue.Count != 0)
            {
                List<int> list = relationship.Search(queue.Peek());
                for (int i = 0; i < list.Count; i++)
                {
                    if (relationship.unit[relationship.dictionary[list[i]]].visit == false)
                    {
                        queue.Enqueue(list[i]);

                        Recordset.SeekID(list[i]);
                        Recordset.Edit();
                        Recordset.SetFieldValue("SmUserID", 2);

                        Recordset.Update();
                        relationship.unit[relationship.dictionary[list[i]]].visit = true;
                    }


                } queue.Dequeue();
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (dataSet.Type != DatasetType.Point)
            {
                MessageBox.Show("请选择一个点数据集");
                return;
            }
            StartPoints = dataSet;

        }
        
     

      

    }
}
